#include "Precompiled.h"
#include "GraphicsPipeline11.h"
#include "../Render/Pipeline11/EntityRenderInitializer11.h"

namespace Game {
namespace GraphicsPipeline {

using namespace Game::Render::Pipeline11;

GraphicsPipeline11::GraphicsPipeline11(ID3D11Device* d3dDevice) : d3dDevice(d3dDevice) {
    DXUTSetCallbackD3D11SwapChainResized(GraphicsPipeline11::D3D11SwapChainResizedCallback, this);
    DXUTSetCallbackD3D11FrameRender(GraphicsPipeline11::D3D11FrameRenderCallback, this);
    DXUTSetCallbackD3D11SwapChainReleasing(GraphicsPipeline11::D3D11SwapChainReleasingCallback, this);
}

GraphicsPipeline11::~GraphicsPipeline11() {
    DXUTSetCallbackD3D11SwapChainResized(NULL);
    DXUTSetCallbackD3D11FrameRender(NULL);
    DXUTSetCallbackD3D11SwapChainReleasing(NULL);
}

void GraphicsPipeline11::Finalize() {
    EntityRenderInitializer11::Finalize(*this->GetEntityRenderManager());
}

void GraphicsPipeline11::Initialize() {
    EntityRenderInitializer11::Initialize(*this->GetEntityRenderManager());
}

void GraphicsPipeline11::FrameRender(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, const double& fTime, const float& fElapsedTime) {
    // Clear render target and the depth stencil
    float ClearColor[4] = { 0.176f, 0.196f, 0.667f, 0.0f };

    ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView();
    ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView();
    pd3dImmediateContext->ClearRenderTargetView(pRTV, ClearColor);
    pd3dImmediateContext->ClearDepthStencilView(pDSV, D3D11_CLEAR_DEPTH, 1.0, 0);
}

void GraphicsPipeline11::OnSwapChainReleasing() {
}

HRESULT GraphicsPipeline11::OnSwapChainResized(ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) {
    return S_OK;
}

void CALLBACK GraphicsPipeline11::D3D11FrameRenderCallback(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, float fElapsedTime, void* pUserContext) {
    return static_cast<GraphicsPipeline11*>(pUserContext)->FrameRender(pd3dDevice, pd3dImmediateContext, fTime, fElapsedTime);
}

void CALLBACK GraphicsPipeline11::D3D11SwapChainReleasingCallback(void* pUserContext) {
    return static_cast<GraphicsPipeline11*>(pUserContext)->OnSwapChainReleasing();
}

HRESULT CALLBACK GraphicsPipeline11::D3D11SwapChainResizedCallback(ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext) {
    return static_cast<GraphicsPipeline11*>(pUserContext)->OnSwapChainResized(pd3dDevice, pSwapChain, pBackBufferSurfaceDesc);
}

}

}
